package com.aididi;

import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Auther: zx.xu
 * @Description:
 */
@RestController
@RequestMapping("/people")
@Slf4j
public class PeopleController {


    @Autowired
    private TransportClient client;

    /**
     * @Description:    根据id查询
     * @Author zx.xu
     * @Param: [id]
     */
    @GetMapping("/query/people/man")
    public ResponseEntity queryById(@RequestParam("id") String id){
        if(id.isEmpty()){
            return new ResponseEntity(HttpStatus.NOT_FOUND);
        }
        GetResponse response = this.client.prepareGet("people","man",id).get();
        if(!response.isExists()){
            return new ResponseEntity(HttpStatus.NOT_FOUND);
        }
        log.info(response.getSourceAsString());
        return new ResponseEntity(response.getSource(), HttpStatus.OK);
    }

    /**
     * @Description:    插入数据
     * @Author zx.xu
     * @Param: [id, name, country, age, brithdate]
     */
    @PutMapping("/add/people/man")
    public ResponseEntity addIndex(@RequestParam("id") String id,String name,
                                   @RequestParam("country") String country,
                                    @RequestParam("age") Integer age,
                                   @RequestParam("brithdate") @DateTimeFormat(pattern = "yyyy-MM-dd HH:ss:mm") Date brithdate){
        try {
            XContentBuilder contentBuilder = XContentFactory.jsonBuilder().startObject()
                    .field("id","4")
                    .field("name","马化腾")
                    .field("country","中国人")
                    .field("age",49)
                    .field("brithdate",brithdate.getTime())
                    .endObject();
            IndexResponse response= this.client.prepareIndex("people","man").setSource(contentBuilder).get();
            return new ResponseEntity(response.getId(),HttpStatus.OK);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("错误消息：{}",e.getMessage(),e);
            return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * @Description:    删除数据
     * @Author zx.xu
     * @Param: [id]
     */
    @DeleteMapping("/del/people/man")
    public ResponseEntity deleteById(@RequestParam("id") String id){
        DeleteResponse response = this.client.prepareDelete("people","man",id).get();
        return new ResponseEntity(response.getResult(),HttpStatus.OK);
    }


    /**
     * @Description:    更新数据
     * @Author zx.xu
     * @Param: [id, name, country, age, brithdate]
     */
    @PostMapping("/update/people/man")
    public ResponseEntity updateById(@RequestParam("id") String id,
                                     @RequestParam(value = "name",required = false)String name,
                                     @RequestParam(value = "country",required = false) String country,
                                     @RequestParam(value = "age",required = false) Integer age,
                                     @RequestParam(value = "brithdate",required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:ss:mm") Date brithdate){
        UpdateRequest request = new UpdateRequest("people","type",id);
        try {
            XContentBuilder contentBuilder = XContentFactory.jsonBuilder().startObject();
            if(!StringUtils.isEmpty(name)) {
                contentBuilder.field("name",name);
            }
            if(!StringUtils.isEmpty(country)) {
                contentBuilder.field("country",country);
            }
            if(!StringUtils.isEmpty(age)) {
                contentBuilder.field("age",age);
            }
            if(!StringUtils.isEmpty(brithdate)) {
                contentBuilder.field("brithdate",brithdate);
            }
            contentBuilder.endObject();
            request.doc(contentBuilder);

        } catch (IOException e) {
            e.printStackTrace();
            return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
        }
        UpdateResponse response =null;
        try {
             this.client.update(request).get();
            return new ResponseEntity(response.getResult().toString(),HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * @Description: 复合查询
     * @Author zx.xu
     * @Param: [name, country, gt_age, lt_age]
     */
    @PostMapping("/querymatch/people/man")
    public ResponseEntity queryMatch(@RequestParam(value = "name",required = false)String name,
                                     @RequestParam(value = "country",required = false) String country,
                                     @RequestParam(value = "gt_age",defaultValue = "0") Integer gt_age,
                                     @RequestParam(value = "lt_age",required = false) Integer lt_age){
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        if(!StringUtils.isEmpty(name)){
            builder.must(QueryBuilders.matchQuery("name",name));
        }
        if(!StringUtils.isEmpty(country)){
            builder.must(QueryBuilders.matchQuery("country",country));
        }
        RangeQueryBuilder rangeQueryBuilder =  QueryBuilders.rangeQuery("age").from(gt_age);
        if(!StringUtils.isEmpty(lt_age) && lt_age > 0){
            rangeQueryBuilder.to(lt_age);
        }
        builder.filter(rangeQueryBuilder);
        SearchRequestBuilder requestBuilder = this.client.prepareSearch("people").setTypes("man")
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                .setQuery(builder).setFrom(0).setSize(10)
                .addSort(SortBuilders.fieldSort("brithdate").order(SortOrder.DESC));
        log.info("查询语句：${}",requestBuilder.toString());
        SearchResponse searchResponse = requestBuilder.get();
        List<Map<String,Object>> result = new ArrayList<>();
        for(SearchHit hit : searchResponse.getHits()){
            result.add(hit.getSource());
        }
        return new ResponseEntity(result,HttpStatus.OK);
    }

}
